package com.blq.web.CustomerRepair.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.blq.api.service.impl.ApiServiceImpl;
import com.blq.common.core.domain.PageQuery;
import com.blq.common.core.domain.entity.SysDept;
import com.blq.common.core.domain.entity.SysDeptInfo;
import com.blq.common.core.domain.entity.SysUser;
import com.blq.common.core.page.TableDataInfo;
import com.blq.common.exception.ServiceException;
import com.blq.common.utils.*;
import com.blq.pay.service.IWxPayService;
import com.blq.system.domain.SysNotice;
import com.blq.system.mapper.SysDeptInfoMapper;
import com.blq.system.mapper.SysDeptMapper;
import com.blq.system.mapper.SysNoticeMapper;
import com.blq.system.mapper.SysUserMapper;
import com.blq.system.service.ISysConfigService;
import com.blq.system.service.impl.SysNoticeServiceImpl;
import com.blq.system.service.impl.SysUserServiceImpl;
import com.blq.utils.SendOrderMsg;
import com.blq.web.CustomerRepair.controller.ComerController;
import com.blq.web.CustomerRepair.domain.CustomerRepair;
import com.blq.web.CustomerRepair.domain.bo.CustomerRepairBo;
import com.blq.web.CustomerRepair.domain.vo.CustomerRepairVo;
import com.blq.web.CustomerRepair.mapper.CustomerRepairMapper;
import com.blq.web.CustomerRepair.service.ICustomerRepairService;
import com.blq.web.PayoutInformation.domain.PayoutInformation;
import com.blq.web.PayoutInformation.mapper.PayoutInformationMapper;
import com.blq.web.customerMode.entiy.Ticket;
import com.blq.web.customerMode.entiy.TrendChartDto;
import com.blq.web.domain.UserMoneyItem;
import com.blq.web.mapper.UserMoneyItemMapper;
import com.blq.web.service.IUserMoneyItemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.blq.common.utils.DateUtils.dateMinusMonth;
import static com.blq.common.utils.DateUtils.dateMinusYear;

/**
 * 客户报修抢修Service业务层处理
 *
 * @author Blq
 * @date 2022-08-31
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CustomerRepairServiceImpl extends ServiceImpl<CustomerRepairMapper, CustomerRepair> implements ICustomerRepairService {

    private final CustomerRepairMapper baseMapper;
    @Autowired
    private SysNoticeServiceImpl sysNoticeService;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysNoticeMapper sysNoticeMapper;
    @Autowired
    private CustomerRepairMapper customerRepairMapper;
//    @Autowired
//    private ApiServiceImpl apiService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ComerController comerController;

    private final SysDeptInfoMapper sysDeptInfoMapper;
    private final ISysConfigService sysConfigService;
    private final PayoutInformationMapper payoutInformationMapper;
    private final UserMoneyItemMapper userMoneyItemMapper;
    private final IUserMoneyItemService userMoneyItemService;

    @Override
    public List<Map<String,Object>> selectSalesVolume(TrendChartDto trendChart){
        return customerRepairMapper.selectSalesVolume(trendChart);
    }

    @Override
    public List<Map<String,Object>> selectReceiveNum(TrendChartDto trendChart){
        return customerRepairMapper.selectReceiveNum(trendChart);
    }

    @Override
    public List<Map<String,Object>> selectUserOrderAndPrice(TrendChartDto trendChart){
        return customerRepairMapper.selectUserOrderAndPrice(trendChart);
    }

    @Override
    public List<CustomerRepair> queryPendingOrder(JSONObject jsonObject){
        //liaisonPhone
        if (StringUtils.isNotBlank(jsonObject.getString("receiverBy"))) {
            SysUser user = sysUserMapper.selectById(jsonObject.getString("receiverBy"));
            if (user != null) {
                jsonObject.put("liaisonPhone", user.getPhonenumber());
            }
        }
        return customerRepairMapper.selectPendingOrder(jsonObject);
    }

    @Override
    public List<CustomerRepair> queryByUserIdAndStatus(JSONObject jsonObject){
//        String userId = jsonObject.getString("userId");
//        String status = jsonObject.getString("status");
        if (StringUtils.isNotBlank(jsonObject.getString("userId"))) {
            SysUser user = sysUserMapper.selectById(jsonObject.getString("userId"));
            if (user != null) {
                jsonObject.put("liaisonPhone", user.getPhonenumber());
            }
        }
        jsonObject.put("status", jsonObject.getString("status"));
        return customerRepairMapper.selectByUserIdAndStatus(jsonObject);
    }

    @Override
    public List<CustomerRepair> viewAllUserOrders(JSONObject jsonObject){
//        String userId = jsonObject.getString("userId");
//        String status = jsonObject.getString("status");
        if (StringUtils.isNotBlank(jsonObject.getString("userId"))) {
            SysUser user = sysUserMapper.selectById(jsonObject.getString("userId"));
            if (user != null) {
                jsonObject.put("liaisonPhone", user.getPhonenumber());
            }
        }
        jsonObject.put("status", jsonObject.getString("status"));
        return customerRepairMapper.viewAllUserOrders(jsonObject);
    }

    @Override
    public List<CustomerRepair> selectByCustomerRepair(CustomerRepair customerRepair, PageQuery pageQuery){
        return customerRepairMapper.selectByCustomerRepair(pageQuery.build(),customerRepair);
    }

    @Override
    public Map<String,Object> queryVariousOrders(JSONObject jsonObject) {
        String userId = jsonObject.getString("loginmanId");
        String liaisonPhone = null;
        SysUser user = sysUserMapper.selectById(userId);
        if (user != null) {
            liaisonPhone =  user.getPhonenumber();
        }
        Map<String, Object> map = customerRepairMapper.selectOrderStatusNum(userId, liaisonPhone);
        int announcement = 0;
        announcement += customerRepairMapper.selectAnnouncementOfKh(userId);
        announcement += customerRepairMapper.selectAnnouncementOfSf(userId);
        announcement += customerRepairMapper.selectAnnouncementOfSh(userId);
        announcement += customerRepairMapper.selectAnnouncementOfCw(userId);
        map.put("announcement", announcement);
        return map;
    }

    /**
     * 查询客户报修抢修
     */
    @Override
    public CustomerRepairVo queryById(String customerKey) {
        return baseMapper.selectVoById(customerKey);
    }

    /**
     * 查询客户报修抢修列表
     */
    @Override
    public TableDataInfo<CustomerRepairVo> queryPageList(CustomerRepairBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CustomerRepair> lqw = buildQueryWrapper(bo);
//        Page<CustomerRepairVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Page<CustomerRepairVo> result = baseMapper.selectCustomerRepairList(pageQuery.build(), bo);
        Set<String> ids = new HashSet<>();
        for (CustomerRepairVo record : result.getRecords()) {
            if (StringUtils.isNotBlank(record.getReceiverMan())) {
                ids.add(record.getReceiverMan());
                ids.add(record.getReceiverBy());
            }
        }
        if (ids.size() > 0) {
            List<SysUser> sysUsers = sysUserMapper.selectVoById(ids);
            if (sysUsers.size() > 0) {
                for (CustomerRepairVo record : result.getRecords()) {
                    List<String> receiver = new ArrayList<>();
                    List<String> proposer = new ArrayList<>();
                    String receiverMan = record.getReceiverMan();
                    String receiverBy = record.getReceiverBy();
                    if (StringUtils.isNotBlank(receiverMan)) {
                        for (SysUser sysUser : sysUsers) {
                            if (receiverMan.contains(sysUser.getUserId().toString())) {
                                receiver.add(sysUser.getNickName());
                            }
                            if (StringUtils.isNotBlank(receiverBy) && receiverBy.contains(sysUser.getUserId().toString())) {
                                proposer.add(sysUser.getNickName());
                            }
                        }
                        if (receiver.size() > 0) {
                            record.setReceiver(CollUtil.join(receiver, ","));
                        }
                        if (proposer.size() > 0) {
                            record.setProposer(CollUtil.join(proposer, ","));
                        }
                    }
                }
            }
        }

        /*for (CustomerRepairVo record : result.getRecords()) {

            ResultMsg resultMsg = null;
            resultMsg = comerController.editMessage2(record.getCustomerKey(), null,null);
            Object data = resultMsg.getData();
            record.setReceiver(((CustomerRepairVo) data).getReceiver());//负责人
            record.setQuotationPrice(((CustomerRepairVo) data).getQuotationPrice());//费用
            record.setWorkOrderStatus(((CustomerRepairVo) data).getWorkOrderStatus());//工单状态
            record.setTurnoverTime(((CustomerRepairVo) data).getTurnoverTime());//更新时间
            record.setCustomerTimer(((CustomerRepairVo) data).getCustomerTimer());//发起时间
            record.setAppointmentTime(((CustomerRepairVo) data).getAppointmentTime());//发起时间
            record.setAssignmentType(((CustomerRepairVo) data).getAssignmentType());//分配类型
            record.setProposer(((CustomerRepairVo) data).getProposer());//服务人员
        }*/
        return TableDataInfo.build(result);
    }

    /**
     * 查询客户报修抢修列表
     */
    @Override
    public List<CustomerRepairVo> queryList(CustomerRepairBo bo) {
        LambdaQueryWrapper<CustomerRepair> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<CustomerRepair> buildQueryWrapper(CustomerRepairBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CustomerRepair> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerId()), CustomerRepair::getCustomerId, bo.getCustomerId());
        lqw.like(StringUtils.isNotBlank(bo.getCustomerName()), CustomerRepair::getCustomerName, bo.getCustomerName());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerPhone()), CustomerRepair::getCustomerPhone, bo.getCustomerPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerAddress()), CustomerRepair::getCustomerAddress, bo.getCustomerAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerHelp()), CustomerRepair::getCustomerHelp, bo.getCustomerHelp());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerTimer()), CustomerRepair::getCustomerTimer, bo.getCustomerTimer());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerMessage()), CustomerRepair::getCustomerMessage, bo.getCustomerMessage());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerFiles()), CustomerRepair::getCustomerFiles, bo.getCustomerFiles());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerAuto()), CustomerRepair::getCustomerAuto, bo.getCustomerAuto());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerUnit()), CustomerRepair::getCustomerUnit, bo.getCustomerUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getReceiverBy()), CustomerRepair::getReceiverBy, bo.getReceiverBy());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerFlag()), CustomerRepair::getCustomerFlag, bo.getCustomerFlag());
        return lqw;
    }

    /**
     * 新增客户报修抢修
     */
    @Override
    public Boolean insertByBo(CustomerRepairBo bo) {
        CustomerRepair add = BeanUtil.toBean(bo, CustomerRepair.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setCustomerKey(add.getCustomerKey());
        }
        return flag;
    }

    /**
     * 修改客户报修抢修
     */
    @Override
    public Boolean updateByBo(CustomerRepairBo bo) {
        CustomerRepair update = BeanUtil.toBean(bo, CustomerRepair.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CustomerRepair entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除客户报修抢修
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * @Author: zeh
     * 根据员工id获取公司id
     */
    public Long getOrgId(String workerman) {
        SysUser sysUser = sysUserMapper.selectById(workerman);
        if (sysUser != null && sysUser.getDeptId() != null) {
            if (sysUser.getDeptId() == 1613808083627782145L) {
                return sysUser.getDeptId();
            }
            SysDept sysDept = sysDeptMapper.selectById(sysUser.getDeptId());
            if (sysDept != null) {
                if (sysDept.getDeptType() == 1) {
                    return sysUser.getDeptId();
                }
                String[] split = sysDept.getAncestors().split(",");
                for (int i = split.length - 1; i > 1; i--) {
                    SysDept dept = sysDeptMapper.selectById(split[i]);
                    if (dept.getDeptType() == 1) {
                        return dept.getDeptId();
                    }
                }
            }
        }
        throw new ServiceException("获取人员公司信息失败");
    }

    /**
     * @Description 接口描述 :
     * @Params * @param null
     * customerKey : 订单的主键号码
     * customer_player  :  选择师傅ids
     * orderStatus : 修改订单状态码
     * loginmanId : 当前登录人 id
     * @Return
     * @Author xiaw
     * @Date 2022/12/25 0:13
     */
    @Transactional
    @Override
    public ResultMsg updateWorkOrderStatus(JSONObject jsonObject) {

        //根据登录人id查到对应名字,放进去
        String loginmanId = jsonObject.getString("loginmanId");
        String customerKey = jsonObject.getString("customerKey");
        String orderStatus = jsonObject.getString("orderStatus");
        if (StringUtils.isBlank(loginmanId)) return ResultMsg.ARGS_ERROR.setNewErrorMsg("登录人不能为空");
        if (StringUtils.isBlank(customerKey)) return ResultMsg.ARGS_ERROR.setNewErrorMsg("订单号不能为空");
        if (StringUtils.isBlank(orderStatus)) return ResultMsg.ARGS_ERROR.setNewErrorMsg("工单状态不能为空");
        CustomerRepair order = customerRepairMapper.selectById(customerKey);
        boolean customerKey1 = false;
        if ("客户报修抢修".equals(order.getCustomerHelp())) {
            customerKey1 = true;
        }
        //获取公司id
//        Long aLong = apiService.getaLong(loginmanId);
        //数据准备
        Date date = new Date();//  时间
        //  公司id
        Long deptId = sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("user_id", loginmanId)).getDeptId();
        String dept_id = sysDeptMapper.selectOne(new QueryWrapper<SysDept>().eq("dept_id", deptId)).getAncestors();
//        String companyId = dept_id.split(",")[2];
        Long companyId = getOrgId(loginmanId);
        //  工单类型
//        boolean customerKey1 = apiService.EqName(customerKey);

        CustomerRepair customerRepair = new CustomerRepair();
        //如果是派发的订单--需要去查receiver_by然后放入到接单人字段
        CustomerRepair customerRepair1 = customerRepairMapper.selectOne(new QueryWrapper<CustomerRepair>()
                .eq("customer_key", customerKey)
                .select("receiver_by", "customer_designate","customer_auto"));
        if (customerRepair1.getCustomerDesignate() != null){
            customerRepair.setReceiverMan(customerRepair1.getReceiverBy());//派单
        }else {
            if (customerKey1) {//报修
                if (customerRepair1.getCustomerAuto().equals("1")){
                    customerRepair.setReceiverMan(loginmanId);//正常自动接单
                }
            }
        }
        //数据
        customerRepair.setCustomerKey(customerKey);
        customerRepair.setReceiveTime(date);
        customerRepair.setCompanyId(String.valueOf(companyId));
        customerRepair.setUpdateTime(date);
        customerRepair.setUpdateBy(loginmanId);
        //短信提醒
        SysUser smsUser = sysUserMapper.selectById(loginmanId);
//        CustomerRepair order = customerRepairMapper.selectById(customerKey);
        if (StringUtils.isNotBlank(order.getCustomerPhone()) && smsUser != null) {
            SendOrderMsg.sendDIY("尊敬的用户您好，您的<" + order.getCustomerHelp() + ">订单被<" + smsUser.getNickName() + ">[" + smsUser.getPhonenumber() + "]师傅接单，接下来由他完成您的订单。", order.getCustomerPhone(), order.getLiaisonPhone());
        }
        //修改公告
        String content = "尊敬的用户 : 你好 ,您的" + maintenanceType(customerKey) + "订单已接单,点击查看";
        updateNotice(loginmanId, customerKey, "备注", content, "0", null, null, null);
        // 接单
        if (jsonObject.getInteger("orderStatus") == 21) {
            if (!customerKey1) {
                customerRepair.setCustomerFlag("1");
            } else {//保修
                customerRepair.setCustomerFlag("21");
            }
            customerRepairMapper.updateCustomerRepairBykey(customerRepair);
            return ResultMsg.SUCCESS.setNewErrorMsg("接单成功");
        }
        return null;
    }

    @Override
    public Map<String, Object> queryServedCustomerData(String date) throws Exception {
        Map<String,Object>res = new HashMap<>();
        String lastMonth = dateMinusMonth(date);
        String lastYear = dateMinusYear(date);
        Integer number = customerRepairMapper.selectNumberCustomersServedByMonth(null); //已服务用户总数
        Integer currentNumber = customerRepairMapper.selectNumberCustomersServedByMonth(date);//当月已服务用户数
        Integer lastMonthNumber = customerRepairMapper.selectNumberCustomersServedByMonth(lastMonth);//上月已服务用户总数
        Integer lastYearNumber = customerRepairMapper.selectNumberCustomersServedByMonth(lastYear);//去年同月已服务用户总数
        if(lastMonthNumber == 0){
            res.put("monthRadtio",currentNumber);
        }else{
            double monthRadtio = ((double)currentNumber - lastMonthNumber)/lastMonthNumber;//月环比
            res.put("monthRadtio",new BigDecimal(monthRadtio).setScale(2, RoundingMode.UP));
        }
        if(lastYearNumber == 0){
            res.put("yearRadtio",currentNumber);
        }else{
            double yearRadtio =  ((double)currentNumber - lastYearNumber)/lastYearNumber;//月同比
            res.put("yearRadtio",new BigDecimal(yearRadtio).setScale(2, RoundingMode.UP));
        }
        res.put("customerNumber",number);
        return res;
    }

    /**
     * @Author: xiaw
     * 根据订单id获取订单类型
     */
    public String maintenanceType(String customerKey) {
        QueryWrapper<CustomerRepair> wrapper = new QueryWrapper<>();
        wrapper.eq("customer_key", customerKey);
        wrapper.select("customer_help");
        return customerRepairMapper.selectOne(wrapper).getCustomerHelp();
    }

    /**
     * 传入登录人.订单号,备注,更新公告信息
     */
    @Override
    public void updateNotice(String loginmanId,
                             String customerKey,
                             String remark,
                             String content,
                             String user,//用户状态
                             String worker,//工人
                             String Audit,//审核
                             String Finance) {//财务
        //获取用户的名字
        String customer_key = customerRepairMapper.selectOne(new QueryWrapper<CustomerRepair>().eq("customer_key", customerKey)).getCustomerId();
//        String user_id = sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("user_id", customer_key)).getNickName();
        SysNotice sysNotice = new SysNotice();
        if (!StringUtils.isBlank(remark)) sysNotice.setRemark(remark);
        if (!StringUtils.isBlank(user)) sysNotice.setReadNo(user);
        if (!StringUtils.isBlank(Audit)) sysNotice.setReadNoAudit(Audit);
        if (!StringUtils.isBlank(worker)) sysNotice.setReadNoWorker(worker);
        if (!StringUtils.isBlank(Finance)) sysNotice.setReadNoFinance(Finance);
//        sysNotice.setNoticeContent(user_id + "你好:" + content);
        sysNotice.setNoticeContent(content);
        sysNotice.setUpdateTime(new Date());
        if (loginmanId != null) sysNotice.setUpdateBy(loginmanId);
        UpdateWrapper<SysNotice> wrapper = new UpdateWrapper<>();
        wrapper.eq("customer_key", customerKey);
        sysNoticeMapper.update(sysNotice, wrapper);
    }

    /**
     * @Description 接口描述 : 根据登录人id 和订单id 去记录 更新人个更新时间
     * @Params * @param null
     * @Return
     * @Author xiaw
     * @Date 2022/12/25 0:14
     */
    @NotNull
    public boolean updateTimeAndMan(String loginmanId, String customerKey) {
        //根据用户id查询用户名字
        SysUser sysUser = sysUserMapper.selectone(loginmanId);
        Long userId = sysUser.getUserId();
        String nickName = userId.toString();
        //记录更新者和更新时间
        UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
        wrapper.eq("customer_key", customerKey);
        wrapper.set("update_by", nickName);
        wrapper.set("update_time", new Date());
        boolean update = update(wrapper);

        return update;
    }

    @Override
    public void timeoutToOrderPool() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    Map<String, String> map1 = new HashMap<>();
                    map1.put("beginTime", "19:00:00");
                    Map<String, String> map2 = new HashMap<>();
                    map2.put("endTime", "08:00:00");
                    List<Map<String, String>> list = new ArrayList<>();
                    list.add(map1);
                    list.add(map2);
                    // 下午7点到早上8点范围内不执行
                    if (!DateUtils.isEffectiveDate(null, list)) {
                        List<CustomerRepair> customerRepairs = baseMapper.selectTimeoutOrder(20);
                        if (customerRepairs.size() > 0) {
                            for (CustomerRepair customerRepair : customerRepairs) {
                            /*customerRepair.setCustomerFlag("99");
                            customerRepair.setUpdateTime(new Date());
                            baseMapper.updateById(customerRepair);*/
                                UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
                                wrapper.eq("customer_key", customerRepair.getCustomerKey());
                                wrapper.set("customer_flag", "99");
                                wrapper.set("company_id", null);
                                wrapper.set("update_time", new Date());
                                wrapper.set("receiver_by", null);
                                wrapper.set("receiver_man",null);
                                wrapper.set("receive_time",null);
                                baseMapper.update(null, wrapper);
                                //短信提醒
                                if (StringUtils.isNotBlank(customerRepair.getReceiverBy())) {
                                    String[] rs = customerRepair.getReceiverBy().split(",");
                                    SysUser smsUser = sysUserMapper.selectById(rs[0]);
                                    if (smsUser != null) {
                                        SendOrderMsg.sendDIY("提醒：您有一份<" + customerRepair.getCustomerHelp() + ">订单因超过20分钟未接单，系统已自动将此工单转到工单池。", smsUser.getPhonenumber());
                                    }
                                }
                                poolSendWorker(customerRepair);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    TimeUnit.SECONDS.sleep(60);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.setName("超时工单处理");
        thread.start();
    }

    /**
     * 短信提醒该区域各服务商默认接单人有新单子
     * @param order
     */
    public void poolSendWorker(CustomerRepair order) {
        // 短信提醒该区域各服务商默认接单人有新单子
        List<SysDept> sysDepts = sysDeptMapper.selectList(new QueryWrapper<SysDept>().eq("type_id", 3)
                .eq("del_flag", 0).eq("dept_type", 1)
                .eq("city", order.getCity()).eq("area", order.getArea()));
        for (SysDept dept : sysDepts) {
            if (dept.getReceiver() == 1) {
                List<SysUser> users = sysUserMapper.selectWorkerByDept(dept.getDeptId().toString(), "worker");
                for (SysUser user : users) {
                    if (user.getReceiver() == 1) {
                        SendOrderMsg.sendDIY("新单来啦！提醒：订单池有一份<" + order.getCustomerHelp() + ">新订单进来了，速速抢单。", user.getPhonenumber());
                    }
                }
            }
        }
    }

    /**
     * 师傅现场收款成功，记录到钱包明细
     * @param orderId
     */
    @Override
    @Transactional
    public void workerOnSitePayment(String orderId) {
        CustomerRepair customerRepair = baseMapper.selectById(orderId);
        String liaison = customerRepair.getLiaison();
        String liaisonPhone = customerRepair.getLiaisonPhone();
        String phone = liaisonPhone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2");
        SysUser sysUser = sysUserMapper.selectById(customerRepair.getReceiverMan());
        if (sysUser == null) {
            return;
        }
        PayoutInformation payout = payoutInformationMapper.selectOne(new QueryWrapper<PayoutInformation>().eq("customer_key", orderId));
        if (payout == null) {
            return;
        }
        //订单总金额
        BigDecimal price = payout.getPayoutPrice();
        // 钱包明细记录师傅现场收款
        UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName(), 1
                ,StringUtils.format("【{}】的订单现场收款{}元", liaison + phone, price),
                price, Long.valueOf(orderId), 2, 4);
        userMoneyItemMapper.insert(moneyItem);
        UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
        wrapper.eq("customer_key", customerRepair.getCustomerKey());
        wrapper.set("payoff_state", 2);
        baseMapper.update(null, wrapper);

    }

    @Override
    public void toPayoffOrder() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    List<CustomerRepair> customerRepairs = baseMapper.selectToPayoffOrder(null, 0);
                    if (customerRepairs.size() > 0) {
//                        String ratio = sysConfigService.selectConfigByKey("order.worker.ratio");
                        for (CustomerRepair customerRepair : customerRepairs) {
                            payoffOrder(customerRepair);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    TimeUnit.MINUTES.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.setName("订单结算");
        thread.start();
    }

    @Override
    @Transactional
    public void payoffOrder(String orderId) {
        CustomerRepair customerRepair = baseMapper.selectById(orderId);
        if (!"客户报修抢修".equals(customerRepair.getCustomerHelp()) || customerRepair.getPayoffState() == null || customerRepair.getPayoffState() != 0) {
            return;
        }
        payoffOrder(customerRepair);
    }

    /**
     * 结算订单（订单分账给服务商和接单师傅，只做零钱记录，暂不到账，24小时后执行打款）
     * @param customerRepair
     */
    @Transactional
    public void payoffOrder(CustomerRepair customerRepair) {
        String orderId = customerRepair.getCustomerKey();
        String liaison = customerRepair.getLiaison();
        String liaisonPhone = customerRepair.getLiaisonPhone();
        String phone = liaisonPhone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2");
        PayoutInformation payout = payoutInformationMapper.selectOne(new QueryWrapper<PayoutInformation>().eq("customer_key", orderId));
        if (payout == null) {
            return;
        }
        SysDept sysDept = sysDeptMapper.selectById(customerRepair.getCompanyId());
        if (sysDept == null) {
            return;
        }
        SysUser sysUser = sysUserMapper.selectById(customerRepair.getReceiverMan());
        if (sysUser == null) {
            return;
        }
        // 平台配置的服务商分账比例
        String serviceRatio = sysConfigService.selectConfigByKey("order.service.ratio");
        // 服务商分账比例（判断取公司配置还是公司特殊配置）
        String orderRatio = sysDept.getOrderRatioType() == 1 ? sysDept.getOrderRatio() : serviceRatio;
        // 若没有配置则默认为0
        orderRatio = StringUtils.isBlank(orderRatio) ? "0" : orderRatio;
        // 师傅分账比例（判断取公司配置还是个人特殊配置）
        String workerRatio = sysUser.getWorkerRatioType() == 1 ? sysUser.getWorkerRatio() : sysDept.getWorkerRatio();
        // 若没有配置则默认为0
        workerRatio = StringUtils.isBlank(workerRatio) ? "0" : workerRatio;
        // 若服务商与师傅分账比例之和大于1则跳过处理
        /*double value = new BigDecimal(orderRatio).add(new BigDecimal(workerRatio)).doubleValue();
        if (value > 1) {
            log.error("【{}】的订单服务商与师傅分账比例之和大于1，分账失败。", liaison + liaisonPhone);
            return;
        }*/
        if (Double.parseDouble(orderRatio) > 1) {
            log.error("【{}】的订单服务商的分账比例大于1，分账失败。", liaison + liaisonPhone);
            return;
        }
        if (Double.parseDouble(workerRatio) > 1) {
            log.error("【{}】的订单师傅的分账比例大于1，分账失败。", liaison + liaisonPhone);
            return;
        }
        //订单总金额
        BigDecimal price = payout.getPayoutPrice();
        // 如果是现场支付，钱给了师傅
        if (payout.getPaymentMethod() == 2) {
            // 钱包明细记录师傅现场收款
            UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName() , 1
                    ,StringUtils.format("【{}】的订单现场收款{}元", liaison + phone, price),
                    price, Long.valueOf(orderId), 2, 4);
            userMoneyItemMapper.insert(moneyItem);
            UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
            wrapper.eq("customer_key", customerRepair.getCustomerKey());
            wrapper.set("payoff_state", 2);
            baseMapper.update(null, wrapper);
        } else {
            //计算服务商总应收(平台收取一定服务费)
            if (!"0".equals(orderRatio)) {
                BigDecimal price2 = AmountCalUtils.mulMoney(price, new BigDecimal(orderRatio));
                // 服务商实际应收 = 总应收 - 师傅应收(总应收 * 师傅分账比例)
                if (!"1".equals(workerRatio)) {
                    BigDecimal deptRatio = AmountCalUtils.sub(BigDecimal.ONE, workerRatio);
                    BigDecimal money = AmountCalUtils.mulMoney(price2, deptRatio);
                    Integer checkType = (sysDept.getCheckType() == null ? 0 : sysDept.getCheckType());
                    UserMoneyItem moneyItem = new UserMoneyItem(sysDept.getDeptId(), sysDept.getDeptName(), 2
                            , StringUtils.format("【{}】的订单完成到账{}元，公式：{}x{}", liaison + phone, money, price2, deptRatio),
                            money, Long.valueOf(orderId), checkType);
                    userMoneyItemMapper.insert(moneyItem);
                }
                //师傅分账比例有效则执行分账
                if (!"0".equals(workerRatio)) {
                    Integer checkType = (sysUser.getCheckType() == null ? 0 : sysUser.getCheckType());
                    BigDecimal money = AmountCalUtils.mulMoney(price2, new BigDecimal(workerRatio));
                    UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName(), 1
                            , StringUtils.format("【{}】的订单完成到账{}元，公式：{}x{}", liaison + phone, money, price2, workerRatio),
                            money, Long.valueOf(orderId), checkType);
                    userMoneyItemMapper.insert(moneyItem);
                }
            }

            UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
            wrapper.eq("customer_key", customerRepair.getCustomerKey());
            // 1代表已计算并记录分账，2代表分账已生效
            wrapper.set("payoff_state", 1);
            if ("0".equals(orderRatio)) {
                wrapper.set("payoff_state", 2);
            }
            baseMapper.update(null, wrapper);
        }
    }

    @Override
    public void orderPayment() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    List<CustomerRepair> customerRepairs = baseMapper.selectToPayoffOrder(24, 1);
                    if (customerRepairs.size() > 0) {
                        for (CustomerRepair customerRepair : customerRepairs) {
                            orderPayment(customerRepair);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    TimeUnit.MINUTES.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.setName("订单打款");
        thread.start();
    }

    @Transactional
    public void orderPayment(CustomerRepair customerRepair) {
        String orderId = customerRepair.getCustomerKey();
        List<UserMoneyItem> moneyItems = userMoneyItemMapper.selectList(new QueryWrapper<UserMoneyItem>()
                .eq("order_id", orderId));
        for (UserMoneyItem moneyItem : moneyItems) {
            if (moneyItem.getState() == 1) {
                Long objId = moneyItem.getObjId();
                Integer classify = moneyItem.getClassify();
                SysUser sysUser = sysUserMapper.selectById(objId);
                if (sysUser != null) {
                    boolean state = false;
                    if (classify == 0) {
                        BigDecimal userMoney = sysUser.getMoney() == null ? BigDecimal.ZERO : sysUser.getMoney();
                        sysUser.setMoney(moneyItem.getMoney().add(userMoney));
                        sysUserMapper.updateById(sysUser);
                        state = true;
                    }/* else if (classify == 1) {//暂不支持分账到微信，因为如果分账金额大于500会失败等其他限制
                        if (StringUtils.isBlank(sysUser.getOpenid())) {
                            log.error("分账支付失败！用户微信信息不完善");
                            return;
                        }
                        // 执行微信转账
                        state = userMoneyItemService.wxCash(sysUser, moneyItem.getMoney(), classify, 1);
                    }*/ else if (classify == 2) {
                        if (StringUtils.isBlank(sysUser.getZhiFuBaoName()) || StringUtils.isBlank(sysUser.getZhiFuBao())) {
                            log.error("分账支付失败！用户支付宝信息不完善");
                            return;
                        }
                        state = userMoneyItemService.zfbCash(sysUser, moneyItem.getMoney(), classify, 1, moneyItem.getItemId());
                    } else if (classify == 3) {
                        if (StringUtils.isBlank(sysUser.getPayBankUser()) || StringUtils.isBlank(sysUser.getPayBankCard()) ||
                                StringUtils.isBlank(sysUser.getPayBankName()) || StringUtils.isBlank(sysUser.getPayBankPhone())) {
                            log.error("分账支付失败！用户银行卡信息不完善");
                            return;
                        }
                        // 当前银行卡方式采用后台人工处理，处理后工单会自动分账完结
                        return;
                        // 通过支付宝转账到银行卡方式提现（未开通）
                        // state = userMoneyItemService.zfbCash(sysUser, moneyItem.getMoney(), classify, 1, moneyItem.getItemId());
                    } else {
                        log.error("分账支付失败！用户收款方式参数错误");
                        return;
                    }
                    if (state) {
                        moneyItem.setState(2);
                        userMoneyItemMapper.updateById(moneyItem);
                    } else {
                        return;
                    }
                } else {
                    SysDept sysDept = sysDeptMapper.selectById(objId);
                    if (sysDept != null) {
                        SysDeptInfo deptInfo = sysDeptInfoMapper.selectById(sysDept.getDeptId());
                        sysDept.setDeptInfo(deptInfo);
                        boolean state = false;
                        if (classify == 0) {
                            BigDecimal deptMoney = sysDept.getMoney() == null ? BigDecimal.ZERO : sysDept.getMoney();
                            sysDept.setMoney(moneyItem.getMoney().add(deptMoney));
                            sysDeptMapper.updateById(sysDept);
                            state = true;
                        } else if (classify == 2) {
                            if (StringUtils.isBlank(deptInfo.getZhiFuBaoName()) || StringUtils.isBlank(deptInfo.getZhiFuBao())) {
                                log.error("分账支付失败！服务商支付宝信息不完善");
                                return;
                            }
                            state = userMoneyItemService.zfbCash(sysDept, moneyItem.getMoney(), classify, 1, moneyItem.getItemId());
                        } else if (classify == 3) {
                            if (StringUtils.isBlank(deptInfo.getPayBankUser()) || StringUtils.isBlank(deptInfo.getPayBankCard()) ||
                                    StringUtils.isBlank(deptInfo.getPayBankName())) {
                                log.error("分账支付失败！服务商银行卡信息不完善");
                                return;
                            }
                            // 当前银行卡方式采用后台人工处理，处理后工单会自动分账完结
                            return;
                            // 通过支付宝转账到银行卡方式提现（未开通）
                            // state = userMoneyItemService.zfbCash(sysDept, moneyItem.getMoney(), classify, 1, moneyItem.getItemId());
                        } else {
                            log.error("分账支付失败！服务商收款方式参数错误");
                            return;
                        }
                        if (state) {
                            moneyItem.setState(2);
                            userMoneyItemMapper.updateById(moneyItem);
                        } else {
                            return;
                        }
                    }
                }

            }
        }
        UpdateWrapper<CustomerRepair> wrapper = new UpdateWrapper<>();
        wrapper.eq("customer_key", customerRepair.getCustomerKey());
        wrapper.set("payoff_state", 2);
        baseMapper.update(null, wrapper);
    }

}
